Decorator is a useful structural pattern that lets you transparently compose individual objects to dynamically add (or remove) behavioral features. It is one of the classic patterns from Design Patterns: Elements of Reusable Object-Oriented Software. The decorator pattern relies on a recursive structure to add levels of functionality. A decorator is essentially a wrapper that preserves the same abstract interface as the wrapped component; this is why functionality can be added transparently - a client written against the abstract interface of a component is not affected by (and doesn’t have to be aware of) any of the wrappers used.

The decorator base class (possibly abstract) can wrap any component that implements the AbstractComponent interface; crucially, it itself implements the same interface. This has two important consequences. To clients, working with a decorator is no different than working with any ConcreteComponent. For the decorator itself, it means that it can intercept any request, and insert additional logic to run before and/or after the request is forwarded to the wrapped component. The decorator can even decide not to forward the request to the wrapee. Adding or modifying behavior via decorators is especially useful if said behavior is not strictly associated with the concept represented by the underlying component itself, e.g., if the behavior may be something that is relevant only under specific circumstances or conditions. Also, if it doesn’t make sense to imbue every ConcreteComponent with this additional behavior, the pattern makes it easy to decorate only specific objects. In a variation of the pattern where the AbstractComponent is a base class rather than an interface, the pattern can be implemented by having the decorator override virtual methods. One option is to make those methods protected, and have them be called by other methods in the component base class; this provides the base class with a certain level of control over when and how the virtual methods get invoked; this can be utilized to enforce hierarchy-wide invariants.
It is not necessary to have a sub-hierarchy of decorators themselves (i.e., it is not required to have all decorators be derived from a single decorator base class). The key aspect of the pattern, the thing that makes it work, is that decorators implement the abstract component interface. Therefore, the following structure is also an example of the pattern:
One common use of the decorator pattern is to transparently add logging capabilities without polluting the component with the logging code. It is also found in user interface frameworks. Since all decorators implement the same interface, the pattern can also work well with APIs that rely on method chaining.
A number of stream classes is available in .NET, such as FileStream, MemoryStream, etc. All of them derive from tream, an abstract base class that defines the stream interface and some default logic. One of the derivatives is the BufferedStream class, which is a decorator that wraps other streams and adds a buffering layer, in order to improve read and write performance. It accepts the underlying stream through the constructor:
1 2 3using(Stream stream = new BufferedStream(networkStream)) { // work with 'stream'... }
Note that any preexisting code that was using the network stream can remain unchanged when the buffered stream is introduced, as long as it was written in terms of the interface afforded by the stream type.
Here’s another example. WPF defines the aptly named decorator class, a base class from which other classes can be derived to apply various effects to a wrapped control - e.g. borders, the chrome effect, specialized layout, extra rendering layers, etc. It inherits the FrameworkElement class, which is a concrete class that defines the interface WPF uses to work with UI components, as well as certain functionality that can be customized by overriding protected methods. It also defines the child property that holds the wrapee, as well as some framework-internal logic related to setting and removing the child element. To define a ConcreteDecorator, one can inherit from this base class; the framework itself provides several such derivatives. The border class is a relatively simple example; it adds a border to the wrapped component. It achieves this by overriding three methods: MeasureOverride (to negotiate available space with a parent control), ArrangeOverride (to customize sizing and positioning of the child control), and OnRender (actually draws the borders around the child control). These methods are eventually invoked by the framework (directly or indirectly); at runtime, the framework doesn’t need to be specifically aware that there is a border instance involved.
WPF controls are typically laid out in XAML markup, like this:
1 2 3 4 5 6<Border BorderThickness="1" BorderBrush="Gray" CornerRadius="3" Background="LightGray" Width="250" Height="250"> <Canvas Background="LightGray"> <!-- canvas content --> </Canvas> </Border>
Here, the canvas control is placed inside a border; the XAML parser interprets this to mean that an instance of a canvas control should be assigned to the child property of the border. The fact that WPF has to support XAML introduces complexity to the process, but with regard to the decorator pattern, it all comes down to the equivalent of this:
1 2 3 4 5 6Canvas canvas = new Canvas(); canvas.Background = Brushes.LightGray; Border border = new Border(); // set various properties... border.Child = canvas;
In this case, the wrapee is not injected through the constructor, and the child property is used instead. This decision was probably driven by the specific needs of the framework. Typically, the wrapee is passed to the constructor, but this example demonstrates that property and method injection are valid options as well.
Note that in both of these examples the code that actually constructs and composes the instances has to be aware of the decorator-specific interface (in order to be able to inject the wrapee), but that the client code that uses decorated components does not. In a sense, the coupling of construction logic and the decorator-derived types enables clients to remain decoupled, and the decorators to be introduced transparently.
Sometimes, when the decorator doesn’t have wrapee-specific state to maintain, but only adds some bit of functionality, the same decorator can be reused for multiple wrapees. For example, suppose you are iterating over a collection of product objects in order to display them in a product list view. The user can select a specific standard, and when the product list is shown, if a product is not in compliance, the string “(noncompliant)” is appended to the name and certain normally available actions provided by the product class are are diabled. The decorator pattern is a viable approach here, especially since there’s a number of these standards, and there is also a specialized product list view involved that contains code that is written with the assumption that a product collection will be passed in.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class StandardAwareProduct: IProduct {
private Standard standard;
public StandardAwareProduct(Standard standard) {
this.standard = standard;
}
public IProduct Product {
get;
set;
}
public string Name {
get {
string name = this.Product.Name;
bool complies = this.standard.IsInCompliance(this.Product);
string result = complies ? name : $ "{name} (noncompliant)";
return result;
}
}
// intercept and enable/disable certain actions based on compliance (omitted)...
}
To provide the view with the decorated products, an iterator helper method can be used:
1 2 3 4 5 6 7 8 9private IEnumerable < IProduct > EnumerateAsStandardAware( Standard standard, IEnumerable < IProduct > products) { var wrapper = new StandardAwareProduct(standard); foreach(var product in products) { wrapper.Product = product; yield return wrapper; } }
Since all the products in the source collection are checked against the same standard, the StandardAwareProduct decorator can be reused; as the decorator is instantiated only once, the wrapee is injected via a property.
Now all that remains to be done is to change how the constructor of the product view is called; from thisproductList = new ProductListView(products)
to thisproductList = new ProductListView(EnumerateAsStandardAware(standard, products))
The code of ProductListView itself does not require any changes. Same goes for the product class. It is interesting to note that the object returned by the EnumerateAsStandardAware iterator method is itself a decorator over IEnumerable<Product>.
Another example to consider is LINQ. While the lambdas that various LINQ methods take can be seen as an example of the strategy pattern, the methods themselves work as decorators. LINQ is a set of extension methods on the IEnumerable<T> interface; when a method such as where or select is called, a specialized wrapper is returned. However, since these wrappers implement IEnumerable<T> themselves, all of the LINQ extension methods can be called on them as well; which is why call chaining works when method syntax is used.
The following code can be visualized by the diagram below:
1 2var customerIDs = orders.Where(order => order.Date < thresholdDate) .Select(order => order.CustomerID);

Since JavaScript is dynamic, supports duck-typing and uses prototype-based inheritance, it is fairly easy to create decorators in an almost ad hoc fashion. There are several options to consider. One approach is to go the standard route and implement a wrapper in the usual way. Another is to make use of constructor functions to inherit from the decorated component; this results in method calls being automatically forwarded, which simplifies the implementation of the decorators because the programmer only needs to be concerned with the few methods that are relevant to the capabilities of that specific decorator.
In the example below, a PurchaseOrderItem is wrapped into a decorator that adds logging to the setQuantity method. Setting the LoggingPurchaseOrderItem.prototype to the sourcePOItem lets the decorator inherit all the existing properties and methods, and only “override” setQuantity. It acts as a decorator because this mechanism lets it retain the PurchaseOrderItem interface, which in turn makes it transparent to client code (no special treatment is needed).
1
2
3
4
5
6
7
8
9
10
function GetLoggingPurchaseOrderItem(sourcePOItem) {
function LoggingPurchaseOrderItem() {
this.setQuantity = function (value) {
console.log(`Setting quantity to ${value}`);
sourcePOItem.setQuantity(value);
}
}
LoggingPurchaseOrderItem.prototype = sourcePOItem;
return new LoggingPurchaseOrderItem();
}
Since JavaScript methods are just properties on an object, they can be easily replaced. So another way to “decorate” a component, especially if a single method is involved, is to replace an existing method with a custom function that wraps the original one while retaining the same signature. This can be done on the source object or on a copy. If the source object is altered, the change will affect the behavior of any code that references the object and calls the altered method(s). Therefore, some care should be taken with this approach.
1
2
3
4
// replaces the submit function
form.submit = function () {
alert("Cannot submit.");
}
Decorators are more often used to introduce localized alterations of behavior, so a widespread effect is typically undesirable. If that’s the case, or if making copies is not ideal, the inheritance-based approach is a better option.
Some programming languages provide language-level support for decorators as an easy way to add functionality to classes and functions declaratively, by using language keywords and/or specialized syntax. This is a metaprogramming feature; it is roughly speaking similar to, but does not exactly correspond to the decorator pattern in every way, even though it shares the name. Often, this “decorator” feature is used to embellish declarations of classes, properties, methods, and even method parameters; these decorators act as a directive to the compiler or the interpreter, telling it that the code defined by the decorator should be executed before an object instance is returned. This may result in alterations to the behavior of the object, in addition of members, etc. One such language is TypeScript, which implemented an early version of the decorators proposal by the Ecma TC39 committee. This means that the feature will likely become a part of JavaScript as well. The proposal itself is currently in stage 2, and is still subject to change. TypeScript language-level decorators are used extensively by the Angular 2+ framework to define metadata for things like components, directives, etc.
The decorator pattern is a way to transparently attach behavior to an object. The pattern is a composition-based alternative to subclassing, and it makes it easy to alter individual instances, rather than the entire class. Because the wrapped components and the decorators implement the same interface, decorators can be composed recursively and combined in different ways. This provides a way to flexibly support a large number of behaviors with a relatively small number of decorator classes, by mixing and matching decorators. Furthermore, an object can easily be decorated more than once with the same decorator if necessary. If features are provided as decorators, they can be added relatively easily later on during development. This is more flexible than trying to foresee all the needed features upfront; applications that do not need specialized features can remain decoupled from them, as they do not need to import those decorators at all. However, it’s easy to get carried away; keep the code as simple as possible, because decorators introduce a certain level of complexity. If there are too many decorators throughout the system, the code can become hard to understand and debug because of all the levels of indirection involved.